#pragma once
#include <iostream>
#include <string>
#include <stdio.h>
#include <set>
#include <fstream>
#include "Log.hpp"

using namespace std;

class Command
{
private:
    void Load(const string &path)
    {
        fstream in(path);
        if (!in.is_open())
        {
            LOG(FATAL, "open %s fail", path.c_str());
            return;
        }
        //
        string line;
        while (getline(in, line))
        {
            LOG(DEBUG, "load command [%s] success", line.c_str());
            _cmd.insert(line);
        }
        // 关闭文件
        in.close();
    }
    bool SafeCheck(const string &cmd)
    {
        auto iter = _cmd.find(cmd);
        if (iter == _cmd.end())
            return false;
        return true;
    }

public:
    Command(const string &path) : _filepath(path)
    {
        Load(_filepath);
    }

    string Excute(const string &cmd)
    {
        string result;
        if (SafeCheck(cmd))
        {
            FILE *fp = popen(cmd.c_str(), "r");
            if (fp == nullptr)
            {
                return "open fail";
            }
            
            char buffer[1024];
            while (fgets(buffer, sizeof(buffer), fp) != nullptr)
            {
                result += buffer;
            }
            pclose(fp);
        }
        else 
        {
            result = "不安全";
        }
        return result;
    }

    ~Command()
    {
    }

private:
    set<string> _cmd;
    string _filepath;
};